namespace FIREFLYX {
    /**
     * 点击输入管理器 , 统一 mouse 、touch 的单点输入事件
     */
    export class PointManager {
        public static instance: PointManager = new PointManager();

        private readonly _clickLimit = 1.5;  //click的 move 限制
        private _point: Vector2 = new Vector2();
        private _downPoint: Vector2 = new Vector2();
        private _isDown: boolean = false;
        private _touchID: number = -1;

        public init() {
            //绑定事件
            const eMgr = GlobalEventManager.Instance;
            //reg event
            eMgr.addListener("mousedown", (e) => { this.pointDown(e.x, e.y); }, this);
            eMgr.addListener("mouseup", (e) => { this.pointUp(e.x, e.y); }, this);
            eMgr.addListener("mousemove", (e) => { this.pointMove(e.x, e.y); }, this);

            eMgr.addListener("touchstart", this.onTouchstart, this);
            eMgr.addListener("touchend", this.onTouchend, this);
            eMgr.addListener("touchcancel", this.onTouchend, this);
            eMgr.addListener("touchmove", this.onTouchmove, this);

        }

        private onTouchmove(e: TouchEvent) {
            const touch = e.changedTouches[0];
            if (this._touchID == -1 || this._touchID != touch.identifier) return;
            this.pointMove(touch.clientX, touch.clientY);
        }

        private onTouchstart(e: TouchEvent) {
            const touch = e.changedTouches[0];
            if (this._touchID != -1 && this._touchID == touch.identifier) return;
            this._touchID = touch.identifier;
            this.pointDown(touch.clientX, touch.clientY);
        }

        private onTouchend(e: TouchEvent) {
            const touch = e.changedTouches[0];
            if (this._touchID == -1 || this._touchID != touch.identifier) return;
            this._touchID = -1;
            this.pointUp(touch.clientX, touch.clientY);
        }

        private pointMove(x: number, y: number) {
            this._point.set(x, y);
            GlobalEventManager.Instance.dispatchEvent("pointMove", this._point);
        }

        private pointUp(x: number, y: number) {
            if (!this._isDown) return;
            this._isDown = false;
            this._point.set(x, y);
            GlobalEventManager.Instance.dispatchEvent("pointUp", this._point);
            //检查click
            const isClick = Math.abs(this._downPoint.x - x) < this._clickLimit || Math.abs(this._downPoint.y - y) < this._clickLimit;
            if (isClick) {
                GlobalEventManager.Instance.dispatchEvent("pointClick", this._point);
            }
        }

        private pointDown(x: number, y: number) {
            if (this._isDown) return;
            this._point.set(x, y);
            this._downPoint.set(x, y);
            this._isDown = true;
            GlobalEventManager.Instance.dispatchEvent("pointDown", this._point);
        }

    }
}
